home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Socket.java < prev    next >
Text File  |  1998-09-22  |  15KB  |  431 lines

  1. /*
  2.  * @(#)Socket.java    1.30 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.net;
  16.  
  17. import java.io.InputStream;
  18. import java.io.OutputStream;
  19. import java.io.IOException;
  20. import java.io.InterruptedIOException;
  21.  
  22. /**
  23.  * This class implements client sockets (also called just 
  24.  * "sockets"). A socket is an endpoint for communication 
  25.  * between two machines. 
  26.  * <p>
  27.  * The actual work of the socket is performed by an instance of the 
  28.  * <code>SocketImpl</code> class. An application, by changing 
  29.  * the socket factory that creates the socket implementation, 
  30.  * can configure itself to create sockets appropriate to the local 
  31.  * firewall. 
  32.  *
  33.  * @author  unascribed
  34.  * @version 1.30, 07/01/98
  35.  * @see     java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  36.  * @see     java.net.SocketImpl
  37.  * @since   JDK1.0
  38.  */
  39. public  
  40. class Socket {
  41.     /**
  42.      * The implementation of this Socket.
  43.      */
  44.     SocketImpl impl;
  45.  
  46.     /**
  47.      * Creates an unconnected socket, with the
  48.      * system-default type of SocketImpl.
  49.      *
  50.      * @since   JDK1.1
  51.      */
  52.     protected Socket() {
  53.     impl = (factory != null) ? factory.createSocketImpl() : 
  54.         new PlainSocketImpl();
  55.     }
  56.  
  57.     /**
  58.      * Creates an unconnected Socket with a user-specified
  59.      * SocketImpl.
  60.      * <P>
  61.      * The <i>impl</i> parameter is an instance of a <B>SocketImpl</B> 
  62.      * the subclass wishes to use on the Socket. 
  63.      *
  64.      * @since   JDK1.1
  65.      */
  66.     protected Socket(SocketImpl impl) throws SocketException {
  67.     this.impl = impl;
  68.     }
  69.  
  70.     /** 
  71.      * Creates a stream socket and connects it to the specified port 
  72.      * number on the named host. 
  73.      * <p>
  74.      * If the application has specified a server socket factory, that 
  75.      * factory's <code>createSocketImpl</code> method is called to create 
  76.      * the actual socket implementation. Otherwise a "plain" socket is created.
  77.      *
  78.      * @param      host   the host name.
  79.      * @param      port   the port number.
  80.      * @exception  IOException  if an I/O error occurs when creating the socket.
  81.      * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  82.      * @see        java.net.SocketImpl
  83.      * @see        java.net.SocketImplFactory#createSocketImpl()
  84.      * @since      JDK1.0
  85.      */
  86.     public Socket(String host, int port)
  87.     throws UnknownHostException, IOException
  88.     {
  89.     this(InetAddress.getByName(host), port, null, 0, true);
  90.     }
  91.  
  92.     /** 
  93.      * Creates a stream socket and connects it to the specified port 
  94.      * number at the specified IP address. 
  95.      * <p>
  96.      * If the application has specified a socket factory, that factory's 
  97.      * <code>createSocketImpl</code> method is called to create the 
  98.      * actual socket implementation. Otherwise a "plain" socket is created.
  99.      *
  100.      * @param      address   the IP address.
  101.      * @param      port      the port number.
  102.      * @exception  IOException  if an I/O error occurs when creating the socket.
  103.      * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  104.      * @see        java.net.SocketImpl
  105.      * @see        java.net.SocketImplFactory#createSocketImpl()
  106.      * @since      JDK1.0
  107.      */
  108.     public Socket(InetAddress address, int port) throws IOException {
  109.     this(address, port, null, 0, true);
  110.     }
  111.  
  112.     /** 
  113.      * Creates a socket and connects it to the specified remote host on
  114.      * the specified remote port. The Socket will also bind() to the local
  115.      * address and port supplied.
  116.      * @param host the name of the remote host
  117.      * @param port the remote port
  118.      * @param localAddr the local address the socket is bound to
  119.      * @param localPort the local port the socket is bound to
  120.      * @since   JDK1.1
  121.      */
  122.     public Socket(String host, int port, InetAddress localAddr, 
  123.           int localPort) throws IOException {
  124.     this(InetAddress.getByName(host), port, localAddr, localPort, true);
  125.     }
  126.  
  127.     /** 
  128.      * Creates a socket and connects it to the specified remote address on
  129.      * the specified remote port. The Socket will also bind() to the local
  130.      * address and port supplied.
  131.      * @param address the remote address
  132.      * @param port the remote port
  133.      * @param localAddr the local address the socket is bound to
  134.      * @param localPort the local port the socket is bound to
  135.      * @since   JDK1.1
  136.      */
  137.     public Socket(InetAddress address, int port, InetAddress localAddr, 
  138.           int localPort) throws IOException {
  139.               this(address, port, localAddr, localPort, true);
  140.     };             
  141.  
  142.     /**
  143.      * Creates a stream socket and connects it to the specified port 
  144.      * number on the named host. 
  145.      * <p>
  146.      * If the stream argument is <code>true</code>, this creates a 
  147.      * stream socket. If the stream argument is <code>false</code>, it 
  148.      * creates a datagram socket. 
  149.      * <p>
  150.      * If the application has specified a server socket factory, that 
  151.      * factory's <code>createSocketImpl</code> method is called to create 
  152.      * the actual socket implementation. Otherwise a "plain" socket is created.
  153.      *
  154.      * @param      host     the host name.
  155.      * @param      port     the port number.
  156.      * @param      stream   a <code>boolean</code> indicating whether this is
  157.      *                      a stream socket or a datagram socket.
  158.      * @exception  IOException  if an I/O error occurs when creating the socket.
  159.      * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  160.      * @see        java.net.SocketImpl
  161.      * @see        java.net.SocketImplFactory#createSocketImpl()
  162.      * @since      JDK1.0
  163.      * @deprecated Use DatagramSocket instead for UDP transport.
  164.      */
  165.     public Socket(String host, int port, boolean stream) throws IOException {
  166.     this(InetAddress.getByName(host), port, null, 0, stream);
  167.     }
  168.  
  169.     /**
  170.      * Creates a socket and connects it to the specified port number at 
  171.      * the specified IP address. 
  172.      * <p>
  173.      * If the stream argument is <code>true</code>, this creates a 
  174.      * stream socket. If the stream argument is <code>false</code>, it 
  175.      * creates a datagram socket. 
  176.      * <p>
  177.      * If the application has specified a server socket factory, that 
  178.      * factory's <code>createSocketImpl</code> method is called to create 
  179.      * the actual socket implementation. Otherwise a "plain" socket is created.
  180.      *
  181.      * @param      address   the IP address.
  182.      * @param      port      the port number.
  183.      * @param      stream    if <code>true</code>, create a stream socket;
  184.      *                       otherwise, create a datagram socket.
  185.      * @exception  IOException  if an I/O error occurs when creating the socket.
  186.      * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  187.      * @see        java.net.SocketImpl
  188.      * @see        java.net.SocketImplFactory#createSocketImpl()
  189.      * @since      JDK1.0
  190.      * @deprecated Use DatagramSocket instead for UDP transport.
  191.      */
  192.     public Socket(InetAddress host, int port, boolean stream) throws IOException {
  193.     this(host, port, null, 0, stream);
  194.     }
  195.     
  196.     private Socket(InetAddress address, int port, InetAddress localAddr, 
  197.           int localPort, boolean stream) throws IOException {
  198.     this();
  199.  
  200.     if (port < 0 || port > 0xFFFF) {
  201.         throw new IllegalArgumentException("port out range:"+port);
  202.     }
  203.  
  204.     if (localPort < 0 || localPort > 0xFFFF) {
  205.         throw new IllegalArgumentException("port out range:"+localPort);
  206.     }
  207.  
  208.     SecurityManager security = System.getSecurityManager();
  209.     if (security != null) {
  210.         security.checkConnect(address.getHostAddress(), port);
  211.     }
  212.  
  213.     try {
  214.         impl.create(stream); 
  215.         if (localAddr != null || localPort > 0) {
  216.         if (localAddr == null) {
  217.             localAddr = InetAddress.anyLocalAddress;
  218.         }
  219.         impl.bind(localAddr, localPort);
  220.         }
  221.         impl.connect(address, port);
  222.     } catch (SocketException e) {
  223.         impl.close();
  224.         throw e;
  225.     }
  226.     }
  227.  
  228.     /**
  229.      * Returns the address to which the socket is connected.
  230.      *
  231.      * @return  the remote IP address to which this socket is connected.
  232.      * @since   JDK1.0
  233.      */
  234.     public InetAddress getInetAddress() {
  235.     return impl.getInetAddress();
  236.     }
  237.  
  238.     /**
  239.      * Gets the local address to which the socket is bound.
  240.      *
  241.      * @since   JDK1.1
  242.      */
  243.     public InetAddress getLocalAddress() {
  244.     InetAddress in = null;
  245.     try {
  246.         in = (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR);
  247.     } catch (Exception e) {
  248.         in = InetAddress.anyLocalAddress; // "0.0.0.0"
  249.     }
  250.     return in;
  251.     }
  252.  
  253.     /**
  254.      * Returns the remote port to which this socket is connected.
  255.      *
  256.      * @return  the remote port number to which this socket is connected.
  257.      * @since   JDK1.0
  258.      */
  259.     public int getPort() {
  260.     return impl.getPort();
  261.     }
  262.  
  263.     /**
  264.      * Returns the local port to which this socket is bound.
  265.      *
  266.      * @return  the local port number to which this socket is connected.
  267.      * @since   JDK1.0
  268.      */
  269.     public int getLocalPort() {
  270.     return impl.getLocalPort();
  271.     }
  272.  
  273.     /**
  274.      * Returns an input stream for this socket.
  275.      *
  276.      * @return     an input stream for reading bytes from this socket.
  277.      * @exception  IOException  if an I/O error occurs when creating the
  278.      *               input stream.
  279.      * @since      JDK1.0
  280.      */
  281.     public InputStream getInputStream() throws IOException {
  282.     return impl.getInputStream();
  283.     }
  284.  
  285.     /**
  286.      * Returns an output stream for this socket.
  287.      *
  288.      * @return     an output stream for writing bytes to this socket.
  289.      * @exception  IOException  if an I/O error occurs when creating the
  290.      *               output stream.
  291.      * @since      JDK1.0
  292.      */
  293.     public OutputStream getOutputStream() throws IOException {
  294.     return impl.getOutputStream();
  295.     }
  296.  
  297.     /**
  298.      * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
  299.      *
  300.      * @since   JDK1.1
  301.      */
  302.     public void setTcpNoDelay(boolean on) throws SocketException {
  303.     impl.setOption(SocketOptions.TCP_NODELAY, new Boolean(on));
  304.     }
  305.  
  306.     /**
  307.      * Tests if TCP_NODELAY is enabled.
  308.      *
  309.      * @since   JDK1.1
  310.      */
  311.     public boolean getTcpNoDelay() throws SocketException {
  312.     return ((Boolean) impl.getOption(SocketOptions.TCP_NODELAY)).booleanValue();
  313.     }
  314.  
  315.     /**
  316.      * Enable/disable SO_LINGER with the specified linger time.  
  317.      *
  318.      * @since   JDK1.1
  319.      */
  320.     public void setSoLinger(boolean on, int val) throws SocketException {
  321.     if (!on) {
  322.         impl.setOption(SocketOptions.SO_LINGER, new Boolean(on));
  323.     } else {
  324.         impl.setOption(SocketOptions.SO_LINGER, new Integer(val));
  325.     }
  326.     }
  327.  
  328.     /**
  329.      * Returns setting for SO_LINGER. -1 returns implies that the
  330.      * option is disabled.
  331.      *
  332.      * @since   JDK1.1
  333.      */
  334.     public int getSoLinger() throws SocketException {
  335.     Object o = impl.getOption(SocketOptions.SO_LINGER);
  336.     if (o instanceof Integer) {
  337.         return ((Integer) o).intValue();
  338.     } else {
  339.         return -1;
  340.     }
  341.     }
  342.  
  343.     /**
  344.      *  Enable/disable SO_TIMEOUT with the specified timeout, in
  345.      *  milliseconds.  With this option set to a non-zero timeout,
  346.      *  a read() call on the InputStream associated with this Socket
  347.      *  will block for only this amount of time.  If the timeout expires,
  348.      *  a <B>java.io.InterruptedIOException</B> is raised, though the
  349.      *  Socket is still valid. The option <B>must</B> be enabled
  350.      *  prior to entering the blocking operation to have effect. The 
  351.      *  timeout must be > 0.
  352.      *  A timeout of zero is interpreted as an infinite timeout.
  353.      *
  354.      * @since   JDK 1.1
  355.      */
  356.     public synchronized void setSoTimeout(int timeout) throws SocketException {
  357.     impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  358.     }
  359.  
  360.     /**
  361.      * Returns setting for SO_TIMEOUT.  0 returns implies that the
  362.      * option is disabled (i.e., timeout of infinity).
  363.      *
  364.      * @since   JDK1.1
  365.      */
  366.     public synchronized int getSoTimeout() throws SocketException {
  367.     Object o = impl.getOption(SocketOptions.SO_TIMEOUT);
  368.     /* extra type safety */
  369.     if (o instanceof Integer) {
  370.         return ((Integer) o).intValue();
  371.     } else {
  372.         return 0;
  373.     }
  374.     }
  375.  
  376.     /**
  377.      * Closes this socket. 
  378.      *
  379.      * @exception  IOException  if an I/O error occurs when closing this socket.
  380.      * @since      JDK1.0
  381.      */
  382.     public synchronized void close() throws IOException {
  383.     impl.close();
  384.     }
  385.  
  386.     /**
  387.      * Converts this socket to a <code>String</code>.
  388.      *
  389.      * @return  a string representation of this socket.
  390.      * @since   JDK1.0
  391.      */
  392.     public String toString() {
  393.     return "Socket[addr=" + impl.getInetAddress() +
  394.         ",port=" + impl.getPort() + 
  395.         ",localport=" + impl.getLocalPort() + "]";
  396.     }
  397.  
  398.     /**
  399.      * The factory for all client sockets.
  400.      */
  401.     private static SocketImplFactory factory;
  402.  
  403.     /**
  404.      * Sets the client socket implementation factory for the 
  405.      * application. The factory can be specified only once. 
  406.      * <p>
  407.      * When an application creates a new client socket, the socket 
  408.      * implementation factory's <code>createSocketImpl</code> method is 
  409.      * called to create the actual socket implementation. 
  410.      *
  411.      * @param      fac   the desired factory.
  412.      * @exception  IOException  if an I/O error occurs when setting the
  413.      *               socket factory.
  414.      * @exception  SocketException  if the factory is already defined.
  415.      * @see        java.net.SocketImplFactory#createSocketImpl()
  416.      * @since      JDK1.0
  417.      */
  418.     public static synchronized void setSocketImplFactory(SocketImplFactory fac)
  419.     throws IOException
  420.     {
  421.     if (factory != null) {
  422.         throw new SocketException("factory already defined");
  423.     }
  424.     SecurityManager security = System.getSecurityManager();
  425.     if (security != null) {
  426.         security.checkSetFactory();
  427.     }
  428.     factory = fac;
  429.     }
  430. }
  431.